/**
 *
 */
package jp.seraph.tool.motion.runner;

import java.util.List;

import jp.seraph.jsade.action.AgentAction;
import jp.seraph.jsade.core.World;
import jp.seraph.jsade.task.AgentTask;
import jp.seraph.jsade.task.TaskSelector;
import jp.seraph.jsade.util.Executor;
import jp.seraph.jsmf.motion.Motion;
import jp.seraph.jsmf.motion.MotionManager;

/**
 *
 *
 */
public class ListMotionSelector implements TaskSelector {
    public ListMotionSelector(MotionManager aManager, List<String> aMotions) {
        if (aMotions.size() == 0)
            throw new IllegalArgumentException("aMotions");

        mManager = aManager;
        mMotions = aMotions;
        mNext = 0;
        mSend = true;
        mExecuter = new Executor() {
            public void execute() {
            }
        };
    }

    private MotionManager mManager;
    private List<String> mMotions;
    private int mNext;
    private boolean mSend;
    private Executor mExecuter;

    /**
     *
     * @see jp.seraph.jsmf.motion.MotionSelector#getAgentAction(jp.seraph.jsade.core.World)
     */
    public AgentAction getAgentAction(World aWorld) {
        return null;
    }

    /**
     *
     * @see jp.seraph.jsmf.motion.MotionSelector#selectMotion(jp.seraph.jsade.core.World)
     */
    public Motion selectMotion(World aWorld) {
        if (mSend) {
            mSend = false;
            return mManager.getMotion(mMotions.get(mNext++));
        }

        return null;
    }

    /**
     *
     * @see jp.seraph.jsade.task.TaskSelector#selectTask(jp.seraph.jsade.core.World)
     */
    public AgentTask selectTask(World aWorld) {
        if (!mSend)
            return null;

        mSend = false;
        AgentTask tResult = mManager.getMotion(mMotions.get(mNext++)).toTask();

        Executor tListener = new Executor() {
            public void execute() {
                if (mNext < mMotions.size())
                    mSend = true;
                else
                    mExecuter.execute();
            }
        };

        tResult.addCanceledListener(tListener);
        tResult.addCompletedListener(tListener);

        return tResult;
    }

    public void setExecuter(Executor aExecuter) {
        mExecuter = aExecuter;
    }
}
